<?php
/**
 * Created by PhpStorm.
 * User: jswei
 * Date: 2018/5/8
 * Time: 17:16
 */
namespace app\admin\controller;

use jswei\push\drive\GeTuiService;
use jswei\push\sdk\geTui\igetui\IGtTemplateTye;
use think\App;
use think\Controller;
use think\facade\Cache;
use app\admin\model\Admin;
use Firebase\Token\TokenGenerator;
use think\facade\Config;

class Base extends Controller{

    protected $isSink = false;
    protected $sinkMethods = [];
    protected $sign='';
    protected static $token;
    protected static $user;
    protected static $uid=0;
    protected $validate =  null;
    protected $model =  null;

    public function __construct(App $app = null){
        parent::__construct($app);
        if(!$this->isSink){
            if(!in_array(request()->action(),$this->sinkMethods)){
//               $this->_sign();
                $this->_auth();
            }
        }
    }

    /**
     * 重置密码
     * @param $password
     * @param string $hash
     * @param bool $flag
     * @return bool|string
     */
    protected function _password($password,$hash='',$flag=false){
        $pwd = $flag ?
            substr($password.md5($hash),10,15):
            substr(md5($password).md5($hash),10,15);
        return $pwd;
    }

    /**
     * 生成token
     * @param int $uid
     * @return array|mixed
     * @throws \Firebase\Token\TokenException
     */
    public function _token($uid=0){
        if(!$uid) {
            $this->__e('请先登录');
        }
        $token = Cache::store()
            ->get(self::$token['access_token']."_token");
        $time = time();
        $expire = $time + 60 * 60 * 1.5;
        if(!$token){
            $generator = new TokenGenerator(Config::get('app.aseKey'));
            $_token = $generator
                ->setData(array('uid' => "{$uid}"))
                ->create();
            $token = [
                'access_token'=>$_token,
                'expires_in'=>$expire,
                'uid'=>$uid
            ];
            self::$token = $token;
            Cache::store()->set("{$_token}_token",$token);
        }else{
            if(is_array($token) && $token['expires_in'] < $time){
                $this->_removeToken();
                exit(json_encode(['status'=>0, 'code'=>Notify::$Notify_Token失效]));
            }
            if(!is_array($token)){
                $this->_removeToken();
                exit(json_encode(['status'=>0, 'code'=>Notify::$Notify_Token失效]));
            }
        }
        return $token;
    }

    /**
     * 清除token
     */
    protected function _removeToken(){
        $token = self::$token;
        Cache::store()->rm("{$token['access_token']}_token");
    }

    /**
     * 签名验证
     */
    protected function _sign(){
        $params = request()->param();
        $sign = $params['sign'];
        unset($params['sign']);
        $query = '';
        foreach ($params as $k => $v){
            if(is_array($v)){
                $query1 = '';
                foreach ($v as $v1){
                    $query1 .= ','.$v1;
                }
                $query .= '&'.$k.'=['.substr($query1,1).']';
            }else{
                $query .= "&{$k}={$v}";
            }
        }
        if($params['domain']!=config('api.domain')){
            exit(json_encode(['status'=>0,'code'=>Notify::$Notify_非法请求原, 'msg'=> '非法的请求' ]));
        }
        if(time()-ceil($params['timestamp']/1000)>1000){
            exit(json_encode(['status'=>0,'code'=>Notify::$Notify_请求超时,'msg'=>'请求超时']));
        }
        $query =substr($query,1);
        $base64 = str_replace('==','',base64_encode($query));
        $_sign = substr(md5($base64),15);
        if($sign!=$_sign){
            exit(json_encode([ 'status'=>0,'code'=>Notify::$Notify_签名错误, 'msg'=> '签名错误']));
        }
    }

    /**
     *
     */
    protected function _auth(){
        if(!isset(request()->header()['authorization'])){
            exit(json_encode([ 'status'=>0, 'code'=>3000]));
        }
        $token = request()->header()['authorization'];
        $token = str_replace('Bearer ','',$token);
        if(empty($token)){
            exit(json_encode([ 'status'=>0,'code'=>3001]));
        }
        $_token = Cache::store()->get("{$token}_token");
        if($_token['expires_in']<time()){
            exit(json_encode([ 'status'=>0,'code'=>3003]));
        }
        $admin = new Admin();
        $info = $admin->getMember($_token['uid']);
        if(!$info['gid']==-1){
            $info['roles'] =['admin'];
        }else{
            $roles = new \app\admin\model\Roles();
            $_info = $roles->get($info['gid']);
            $info['roles'] = $_info['routes'];
            $info['roles_gid'] = $_info['status']==-1?-1:$_info['id'];
        }
        self::$user = $info;
        self::$uid = $_token['uid'];
    }
    /*
    protected function _auth(){
        if(!isset(request()->header()['authorization'])){
            exit(json_encode([
                'status'=>0,
                'code'=>Notify::$Notify_Token为空
            ]));
        }
        $token = request()->header()['authorization'];
        if(empty($token)){
            exit(json_encode([
                'status'=>0,
                'code'=>Notify::$Notify_Token为空
            ]));
        }
        $_token = Cache::store()->get("{$token}_token");
        if($_token['expires_in']<time()){
            $this->_removeToken();
            exit(json_encode([
                'status'=>0,
                'code'=>Notify::$Notify_Token失效
            ]));
        }
        self::$token = $_token;
    }
     */

    /**
     * 获取用户
     * @return mixed
     */
    public function getUser(){
        $admin = new Admin;
        self::$user = $admin::get(self::$uid);
        unset(self::$user['password']);
        unset(self::$user['hash']);
        return self::$user;
    }

    /**
     * 成功返回
     * @param string $msg
     * @param $data
     * @param int $code
     * @param array $header
     * @param string $type
     * @return \think\Response
     */
    public function __s($msg='',$data='',$code=200,$header=[],$type=''){
        if(is_object($data)){
            $data = $data->toArray();
        }
        $type = $type?$type : config('app.default_return_type');
        $data = (is_array($data) && $data) ? array_merge(['data'=>$data],['code'=>$code,'status'=>1,'msg'=>$msg])
            : ['status'=>1,'msg'=>$msg,'code'=>$code,'data'=>$data];
        return response($data,$code,$header,$type)->send();
    }

    /***
     * 失败返回
     * @param string $msg
     * @param array $data
     * @param int $code
     * @param array $header
     * @param $type
     * @return \think\Response
     */
    public function __e($msg='',$data=[],$code=2010,$header=[],$type=''){
        $type = $type?$type : config('app.default_return_type');
        $data = (is_array($data) && $data) ?
            array_merge(['data'=>$data],['code'=>$code,'status'=>0]) : ['status'=>0,'msg'=>$msg,'code'=>$code];
        $code = $code >500 ? 200 : $code;
        return response($data,$code,$header,$type)->send();
    }

    /**
     * @param $title
     * @param $content
     * @param string $uid
     * @param int $type
     * @param array $data
     * $data = [
     *      'Url'=>'http://baidu.com',
     *      'NotyTitle'=>'软件更新(v4.2.4)',
     *      'NotyContent'=>'针对安卓9.0系统版本手机兼容性修复',
     *      'NotyIcon'=>'http://storev3.iwawo.com/image/HmallLogo.png',
     *      'PopTitle'=>'软件更新(v4.2.4)',
     *      'PopContent'=>'针对安卓9.0系统版本手机兼容性修复',
     *      'PopImage'=>'http://storev3.iwawo.com/image/HmallLogo.png',
     *      'LoadIcon'=>'http://storev3.iwawo.com/image/HmallLogo.png',
     *      'LoadTitle'=>'软件更新(v4.2.4)',
     *      'LoadUrl'=>'http://prstore.oss-cn-hangzhou.aliyuncs.com/apk/HM-190311-40-update.apk'
     *  ];
     * @param array $json
     * @param string $time
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function pushMsg1($title,$content,$uid='',$type=1,$data=[],$json=[],$time=''){
        $getui = \config('getui.');
        $push = new GeTuiService($getui);
        $push->setOfflineExpireTime(3600 * 1000 * 12);
        if($time){  // 定时
            $time = date('YmdHis',strtotime($time));
            $push->setPushTime($time);
        }
        $_type = [
            1 => IGtTemplateTye::notifyInfo,
            2 => IGtTemplateTye::link,
            3 => IGtTemplateTye::download,
            4 => IGtTemplateTye::transmission
        ];
        $push->setTemplateType($_type[$type]);
        $push->setTitle($title);
        $push->setBody($content);
        if ($json){
            $push->setExtendedData($json);
        }
        if ($type==2){
            $push->setLinkUrl($data['Url']);
        }elseif ($type==3){
            $push->setNotyTitle($data['NotyTitle']);
            $push->setNotyContent($data['NotyContent']);
            $push->setNotyIcon($data['NotyIcon']);
            $push->setPopTitle($data['PopTitle']);
            $push->setPopContent($data['PopContent']);
            $push->setPopImage($data['PopImage']);
            $push->setLoadIcon($data['LoadIcon']);
            $push->setLoadTitle($data['LoadTitle']);
            $push->setLoadUrl($data['LoadUrl']);
        }
        $user = new \app\admin\model\User();
        if($uid && !is_array($uid)){
            $client_id = $user->getFieldById($uid,'client_id');
            $res = $push->sendOne($client_id)->getResult();
        }elseif($uid && is_array($uid)){
            $list = $user->field('client_id,device_token')
                ->whereIn('id',$uid)
                ->select();
            $client_id = [];
            foreach ($list as $k => $v){
                if($v['client_id']){
                    array_push($client_id,$v['client_id']);
                }
            }
            if(count($client_id)==0){
                return false;
            }
            $res = $push->sendToUserList($client_id)->getResult();
        }else{
            if($type==3){
                $res = $push->sendAllAndroid()->getResult();
            }else{
                $res = $push->sendAll()->getResult();
            }
        }
        if($res['result']=='ok'){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 获取条件
     * @param array $_where
     * @param null $keys
     * @return array|string
     */
    protected function _where($_where=[],&$keys=null){
        $map=[];
        if (count($_where)==0){
            return $map;
        }
        foreach ($_where as $k => $v){
            if(!is_array($v)){
                $v = json_decode($v,true);
            }
            if (isset($v['field']) ) {
                if(strpos($v['field'],'_.') !== false){
                    $v['field'] = str_replace('_.',
                        $this->model->getTable().'.',$v['field']);
                }
                $keys .= ','.$v['field'];
            }
            if(isset($v['value'])){
                if(empty($v['value']) && $v['op'] != 'aeq'){
                    continue;
                }
                if(trim($v['op'])=='between'){
                    $start = $v['value'][0];
                    $end = $v['value'][1];
                    $map[]=[$v['field'],'between time',[$start,$end]];
                }else if(trim($v['op'])=='like'){
                    $val = trim($v['value']);
                    $map[] = [$v['field'],'like',"%{$val}%"];
                }else if(trim($v['op'])=='today'){
                    $date = date('Y-m-d',time());
                    $start = "{$date} 00:00:00";
                    $end= "{$date} 23:59:59";
                    $map[]=[$v['field'],'between time',[$start,$end]];
                }else if(trim($v['op'])=='neq'){
                    $val = trim($v['value']);
                    $map[] = [$v['field'],'<>',$val];
                }else if(trim($v['op'])=='lt'){
                    $val = trim($v['value']);
                    $map[] = [$v['field'],'<',$val];
                }else if(trim($v['op'])=='gt'){
                    $val = trim($v['value']);
                    $map[] = [$v['field'],'>',$val];
                }else if(trim($v['op'])=='egt'){
                    $val = trim($v['value']);
                    $map[] = [$v['field'],'>=',$val];
                }else if(trim($v['op'])=='aeq'){
                    $val = trim($v['value']);
                    $map[] = [$v['field'],'=',$val];
                }else if(trim($v['op'])=='elt'){
                    $val = trim($v['value']);
                    $map[] = [$v['field'],'<=',$val];
                }else if(is_array($v['value']) && count($v['value']) < 2 ){
                    $val = trim($v['value']);
                    $map[] = ["{$v['field']}",'=',$val];
                }else{
                    $map[] = [$v['field'],$v['op'],$v['value']];
                }
            }
        }
        $keys = substr($keys,1);
        return $map;
    }

    /**
     * 排序
     * @param $order
     * @param null $out
     * @return string
     */
    protected function _order($order){
        $order = explode(',',trim($order));
        $_order = '';
        if($order){
            foreach ($order as $k => $v){
                if(strpos($v,'-')!==false){
                    $_order .= ', ' . substr($v,1) . ' desc';
                }else if(strpos($v,'+')!==false){
                    $_order .=  ', ' .substr($v,1) . ' asc';
                }else if($v){
                    $_order .=  ', ' .$v . ' asc';
                }else{
                    $_order .= ' ';
                }
            }
            $_order = substr($_order,2);
        }
        return $_order;
    }

    /**
     * 插入数据
     * @throws \think\db\exception\BindParamException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function getTablesAttr(){
        $_fields = [];
        $fields = $this->model->field('name,table_name')->select();
        if($fields){
            foreach ($fields as $v){
                array_push($_fields,$v['name']);
            }
        }
        $data = [];
        $db = $this->model->getConfig()['database'];
        $sql1 = "SELECT table_name,table_comment FROM information_schema.TABLES WHERE TABLE_SCHEMA='{$db}'";
        $result1 = $this->model->query($sql1);
        foreach ($result1 as $v){
            if(!in_array($v['table_name'],$_fields)){
                $sql = 'SELECT column_name as name,column_comment as title FROM information_schema.COLUMNS '.
                    'WHERE TABLE_NAME = \''.$v['table_name'].'\' and TABLE_SCHEMA = \''.$db.'\'';
                $result = $this->model->query($sql);
                array_push($data,[
                    'name'=>$v['table_name'],
                    'table_name'=>$v['table_comment'],
                    'table_fields_sort'=> json_encode($result)
                ]);
            }
        }
        if($data){
            $this->model->saveAll($data);
        }
    }

}